package com.laiketui.order.controlller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.laiketui.common.api.PublicOrderService;
import com.laiketui.common.api.order.OrderDubboService;
import com.laiketui.common.process.HandlerOrderContext;
import com.laiketui.core.annotation.ParamsMapping;
import com.laiketui.core.annotation.PreventDuplicateSubmit;
import com.laiketui.core.domain.Result;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.domain.lktconst.DictionaryConst;
import com.laiketui.domain.lktconst.ErrorCode;
import com.laiketui.domain.order.OrderModel;
import com.laiketui.domain.vo.OrderVo;
import com.laiketui.domain.vo.order.*;
import com.laiketui.root.annotation.HttpApiMethod;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wangxian
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    private final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private HandlerOrderContext handlerOrderContext;

    @Autowired
    private PublicOrderService publicOrderService;

    @RequestMapping("/orderlist")
    @HttpApiMethod(urlMapping = {"app.order.index"})
    public Result orderlist(OrderVo vo) {
        try {
            OrderDubboService orderService = null;
            if (Objects.isNull(vo.getType())) {
                orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            } else {
                orderService = handlerOrderContext.getOrderService(vo.getType());
            }
            Map<String, Object> resultMap = orderService.orderList(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @RequestMapping("/settlement")
    @HttpApiMethod(urlMapping = {"app.order.Settlement", "plugin.integral.App.integralAxios", "app.groupbuy.payfor"})
    public Result settlement(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(vo.getType());
            Map<String, Object> resultMap = orderService.settlement(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @RequestMapping("/pthd_settlement")
    @HttpApiMethod(urlMapping = {"app.pthd_groupbuy.payfor"})
    public Result pthdSettlement(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.PTHD_ORDER_HEADER + vo.getType());
            Map<String, Object> resultMap = orderService.settlement(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    private final static ReentrantLock lock = new ReentrantLock();

    @RequestMapping("/payment")
    @HttpApiMethod(urlMapping = {"app.order.payment", "plugin.integral.App.payment", "app.groupbuy.createOrder"})
    @PreventDuplicateSubmit
    public Result payment(OrderVo vo) {
        try {
            if (lock.tryLock()) {
                OrderDubboService orderService = handlerOrderContext.getOrderService(vo.getType());
                Map<String, Object> resultMap = orderService.payment(vo);
                return Result.success(resultMap);
            } else {
                //并发的时候没有拿到锁提示稍后再试
                return Result.error(ErrorCode.BizErrorCode.ERROR_CODE_QWSHZS, "请稍后再试");
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }


    @RequestMapping("/pthd_createOrder")
    @HttpApiMethod(urlMapping = {"app.pthd_groupbuy.createOrder"})
    @PreventDuplicateSubmit
    public Result pthdPayment(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.PTHD_ORDER_HEADER + vo.getType());
            Map<String, Object> resultMap = orderService.payment(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @RequestMapping("/splitOrder")
    @HttpApiMethod(urlMapping = "app.order.leave_Settlement")
    @PreventDuplicateSubmit
    public Result splitOrder(OrderVo vo) {
        try {
            Map<String, String> orderInfoMap = JSON.parseObject(vo.getOrderList(), new TypeReference<Map<String, String>>() {
            });
            OrderModel orderModel = publicOrderService.getOrderInfoById(vo.getStoreId(), null, orderInfoMap.get("sNo"));
            Map<String, Object> resultMap = new HashMap<>(16);
            if (orderModel != null) {
                vo.setsNo(orderModel.getsNo());
                if (DictionaryConst.OrdersType.ORDERS_HEADER_GM.equals(orderModel.getOtype())) {
                    OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
                    resultMap = orderService.splitOrder(vo);
                }
            }
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("加载更多订单")
    @PostMapping("/loadMore")
    public Result loadMore(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.loadMore(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("订单详情")
    @PostMapping("/orderDetails")
    @HttpApiMethod(urlMapping = {"app.order.order_details"})
    public Result orderDetails(OrderVo vo) {
        try {
            OrderDubboService orderService = null;
            if (Objects.isNull(vo.getType())) {
                orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            } else {
                orderService = handlerOrderContext.getOrderService(vo.getType());
            }
            Map<String, Object> resultMap = orderService.orderDetails(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("删除订单")
    @PostMapping("/delOrder")
    @HttpApiMethod(urlMapping = "app.order.del_order")
    @PreventDuplicateSubmit
    public Result delOrder(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.delOrder(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("再次购买")
    @PostMapping("/buyAgain")
    @HttpApiMethod(urlMapping = "app.order.buy_again")
    @PreventDuplicateSubmit
    public Result buyAgain(BuyAgainVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.buyAgain(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("订单搜索")
    @PostMapping("/orderSearch")
    @HttpApiMethod(urlMapping = "app.order.search")
    public Result orderSearch(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.orderSearch(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("删除购物车")
    @PostMapping("/delCart")
    @HttpApiMethod(urlMapping = "app.order.del_cart")
    @PreventDuplicateSubmit
    public Result delCart(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.delCart(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }


    @ApiOperation("获取支付方式")
    @PostMapping("/getPaymentConf")
    public Result getPaymentConf(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.getPaymentConf(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("物流信息展示")
    @PostMapping("/showLogistics")
    @HttpApiMethod(urlMapping = "app.order.logistics")
    public Result showLogistics(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.showLogistics(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("取消售后申请")
    @PostMapping("/cancleApply")
    @PreventDuplicateSubmit
    public Result cancleApply(OrderVo vo, int id) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.cancleApply(vo.getStoreId(), id);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("申请售后")
    @PostMapping("/ReturnData")
    @HttpApiMethod(urlMapping = "app.order.ReturnData")
//    @PreventDuplicateSubmit
    public Result returnData(ApplyReturnDataVo vo, MultipartFile image) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            return Result.success(orderService.returnData(vo, image));
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("售后订单列表")
    @PostMapping("/returnOrderList")
    @HttpApiMethod(urlMapping = "app.order.ReturnDataList")
    public Result returnOrderList(OrderVo vo) {
        try {
            OrderDubboService orderService = null;
            if (!Objects.isNull(vo.getType())) {
                orderService = handlerOrderContext.getOrderService(vo.getType());
            } else {
                orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            }
            Map<String, Object> resultMap = orderService.returnOrderList(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("确认收货")
    @PostMapping("/okOrder")
    @HttpApiMethod(urlMapping = "app.order.ok_Order")
    @PreventDuplicateSubmit
    public Result okOrder(OrderVo vo) {
        try {
            OrderModel orderModel = publicOrderService.getOrderInfoById(vo.getStoreId(), vo.getOrderId(), null);
            vo.setsNo(orderModel.getsNo());
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.okOrder(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("点击退款按钮跳转界面")
    @PostMapping("/returnMethod")
    @HttpApiMethod(urlMapping = "app.order.return_method")
    public Result returnMethod(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.returnMethod(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("获取收货地址和快递信息")
    @PostMapping("/seeSend")
    @HttpApiMethod(urlMapping = "app.order.see_send")
    public Result seeSend(@ParamsMapping("store_id") int storeId, @ParamsMapping("pid") int productId) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.seeSend(storeId, productId);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("保存快递基本信息")
    @PostMapping("/backSend")
    @HttpApiMethod(urlMapping = "app.order.back_send")
    @PreventDuplicateSubmit
    public Result backSend(ReturnGoodsVo returnGoodsVo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.backSend(returnGoodsVo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }


    @ApiOperation("查看提货码")
    @PostMapping("/seeExtractionCode")
    @HttpApiMethod(urlMapping = "app.order.see_extraction_code")
    public Result seeExtractionCode(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.seeExtractionCode(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }


    @ApiOperation("售后订单详情")
    @PostMapping("/returndetails")
    @HttpApiMethod(urlMapping = "app.order.Returndetail")
    public Result returndetails(RefundDetailsVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.returndetails(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("售后确认收货")
    @PostMapping("/confirmReceipt")
    @HttpApiMethod(urlMapping = "app.UserReturn.confirm_receipt")
    @PreventDuplicateSubmit
    public Result confirmReceipt(ReturnConfirmReceiptVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.confirmReceipt(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("取消订单")
    @PostMapping("/cancleOrder")
    @HttpApiMethod(urlMapping = "app.order.removeOrder")
    @PreventDuplicateSubmit
    public Result cancleOrder(OrderVo vo) {
        try {
            OrderModel orderModel = publicOrderService.getOrderInfoById(vo.getStoreId(), vo.getOrderId(), null);
            vo.setsNo(orderModel.getsNo());
            //分销走普通订单流程
            if (DictionaryConst.OrdersType.ORDERS_HEADER_FX.equalsIgnoreCase(orderModel.getOtype())) {
                orderModel.setOtype(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            }
            OrderDubboService orderService = handlerOrderContext.getOrderService(orderModel.getOtype());
            Map<String, Object> resultMap = orderService.cancleOrder(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }


    @ApiOperation("提醒发货")
    @PostMapping("/remindDelivery")
    @HttpApiMethod(urlMapping = "app.order.delivery_delivery")
    @PreventDuplicateSubmit
    public Result remindDelivery(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.remindDelivery(vo);
            return new Result((String) resultMap.get("code"), (String) resultMap.get("message"), new ArrayList<>());
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("撤销审核")
    @PostMapping("/cancelApplication")
    @HttpApiMethod(urlMapping = "app.order.Cancellation_of_application")
    @PreventDuplicateSubmit
    public Result cancelApplication(CancleAfterSaleApplyVo vo) {

        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.cancelApplication(vo);
            return new Result((String) resultMap.get("code"), (String) resultMap.get("message"), new ArrayList<>());
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }

    @ApiOperation("进入订单界面获取可用支付方式")
    @PostMapping("/getPayment")
    @HttpApiMethod(urlMapping = {"app.Order.getPayment"})
    public Result getPayment(OrderVo vo) {
        try {
            OrderDubboService orderService = handlerOrderContext.getOrderService(DictionaryConst.OrdersType.ORDERS_HEADER_GM);
            Map<String, Object> resultMap = orderService.getPayment(vo);
            return Result.success(resultMap);
        } catch (LaiKeAPIException e) {
            return Result.error(e.getCode(), e.getMessage());
        }
    }
}
